// EMERGENT GAME TECHNOLOGIES PROPRIETARY INFORMATION
//
// This software is supplied under the terms of a license agreement or
// nondisclosure agreement with Emergent Game Technologies and may not 
// be copied or disclosed except in accordance with the terms of that 
// agreement.
//
//      Copyright (c) 1996-2007 Emergent Game Technologies.
//      All Rights Reserved.
//
// Emergent Game Technologies, Chapel Hill, North Carolina 27517
// http://www.emergent.net

#include <NiMain.h>
#include <NiAnimation.h>
#include <NiLicense.h>
#include "Main.h"
#include "CeguiRenderClick.h"

NiEmbedGamebryoLicenseCode;
//---------------------------------------------------------------------------
NiApplication* NiApplication::Create()
{
//_CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );
freopen( "f:\\crt_log.txt", "w", stderr);
//_CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_FILE);
_CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE);
_CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_FILE);
_CrtSetReportFile(_CRT_ERROR, _CRTDBG_FILE_STDERR);
    return NiNew YourGame;
}
//---------------------------------------------------------------------------
YourGame::YourGame() : NiApplication("CEGUI Gamebryo Integration",
    DEFAULT_WIDTH, DEFAULT_HEIGHT, true),gui()
{
    //int tmpFlag = _CrtSetDbgFlag( _CRTDBG_REPORT_FLAG );

    // Turn On (OR) - Keep freed memory blocks in the
    // heap's linked list and mark them as freed
    //tmpFlag &= _CRTDBG_ALLOC_MEM_DF;
    //_CrtSetDbgFlag( tmpFlag );
    
    SetMediaPath("../../DATA/");   

    m_bExclusiveMouse = true;
}
//---------------------------------------------------------------------------
void YourGame::UpdateFrame()
{
    NiApplication::UpdateFrame();
    m_spScene->Update(m_fAccumTime);
}
//---------------------------------------------------------------------------
void YourGame::createListContent(void)
{
    using namespace CEGUI;

    WindowManager& winMgr = WindowManager::getSingleton();

    //
    // Combobox setup
    //
    Combobox* cbobox = static_cast<Combobox*>(winMgr.getWindow("Demo7/Window2/Combobox"));
    // add items to the combobox list
    cbobox->addItem(new MyListItem("Combobox Item 1"));
    cbobox->addItem(new MyListItem("Combobox Item 2"));
    cbobox->addItem(new MyListItem("Combobox Item 3"));
    cbobox->addItem(new MyListItem("Combobox Item 4"));
    cbobox->addItem(new MyListItem("Combobox Item 5"));
    cbobox->addItem(new MyListItem("Combobox Item 6"));
    cbobox->addItem(new MyListItem("Combobox Item 7"));
    cbobox->addItem(new MyListItem("Combobox Item 8"));
    cbobox->addItem(new MyListItem("Combobox Item 9"));
    cbobox->addItem(new MyListItem("Combobox Item 10"));

    //
    // Multi-Column List setup
    //
    MultiColumnList* mclbox = static_cast<MultiColumnList*>(winMgr.getWindow("Demo7/Window2/MultiColumnList"));
    // Add some empty rows to the MCL
    mclbox->addRow();
    mclbox->addRow();
    mclbox->addRow();
    mclbox->addRow();
    mclbox->addRow();

    // Set first row item texts for the MCL
    mclbox->setItem(new MyListItem("Laggers World"), 0, 0);
    mclbox->setItem(new MyListItem("yourgame.some-server.com"), 1, 0);
    mclbox->setItem(new MyListItem("1000ms"), 2, 0);

    // Set second row item texts for the MCL
    mclbox->setItem(new MyListItem("Super-Server"), 0, 1);
    mclbox->setItem(new MyListItem("whizzy.fakenames.net"), 1, 1);
    mclbox->setItem(new MyListItem("8ms"), 2, 1);

    // Set third row item texts for the MCL
    mclbox->setItem(new MyListItem("Cray-Z-Eds"), 0, 2);
    mclbox->setItem(new MyListItem("crayzeds.notarealserver.co.uk"), 1, 2);
    mclbox->setItem(new MyListItem("43ms"), 2, 2);

    // Set fourth row item texts for the MCL
    mclbox->setItem(new MyListItem("Fake IPs"), 0, 3);
    mclbox->setItem(new MyListItem("123.320.42.242"), 1, 3);
    mclbox->setItem(new MyListItem("63ms"), 2, 3);

    // Set fifth row item texts for the MCL
    mclbox->setItem(new MyListItem("Yet Another Game Server"), 0, 4);
    mclbox->setItem(new MyListItem("abc.abcdefghijklmn.org"), 1, 4);
    mclbox->setItem(new MyListItem("284ms"), 2, 4);


}
//---------------------------------------------------------------------------
void YourGame::initDemoEventWiring(void)
{
    using namespace CEGUI;

    WindowManager::getSingleton().getWindow("Demo7/Window1/Quit")->
        subscribeEvent(PushButton::EventClicked, 
        Event::Subscriber(&YourGame::handleQuit, this));

    WindowManager::getSingleton().getWindow("Demo7/Window1/Slider1")->
        subscribeEvent(Slider::EventValueChanged, 
        Event::Subscriber(&YourGame::handleSlider, this));

    WindowManager::getSingleton().getWindow("Demo7/Window1/Checkbox")->
        subscribeEvent(Checkbox::EventCheckStateChanged, 
        Event::Subscriber(&YourGame::handleCheck, this));

    WindowManager::getSingleton().getWindow("Demo7/Window1/Radio1")->
        subscribeEvent(RadioButton::EventSelectStateChanged, 
        Event::Subscriber(&YourGame::handleRadio, this));

    WindowManager::getSingleton().getWindow("Demo7/Window1/Radio2")->
        subscribeEvent(RadioButton::EventSelectStateChanged, 
        Event::Subscriber(&YourGame::handleRadio, this));

    WindowManager::getSingleton().getWindow("Demo7/Window1/Radio3")->
        subscribeEvent(RadioButton::EventSelectStateChanged, 
        Event::Subscriber(&YourGame::handleRadio, this));
    if (_CrtCheckMemory() == FALSE)
    {
        NiMessageBox("Memory leak","memory error");
    }
}
//---------------------------------------------------------------------------
bool YourGame::handleQuit(const CEGUI::EventArgs& e)
{

    // signal quit
    QuitApplication();
    // event was handled
    fclose(stderr);
    return true;
}
//---------------------------------------------------------------------------
bool YourGame::handleSlider(const CEGUI::EventArgs& e)
{
    using namespace CEGUI;

    // get the current slider value
    float val = static_cast<Slider*>
        (static_cast<const WindowEventArgs&>(e).window)->getCurrentValue();

    // set the progress for the first bar according to the slider value
    static_cast<ProgressBar*>(WindowManager::getSingleton().getWindow(
        "Demo7/Window2/Progbar1"))->setProgress(val);
    // set second bar's progress - this time the reverse of the first one
    static_cast<ProgressBar*>(WindowManager::getSingleton().getWindow(
        "Demo7/Window2/Progbar2"))->setProgress(1.0f - val);
    // set the alpha on the window containing all the controls.
    WindowManager::getSingleton().getWindow("root")->setAlpha(val);

    // event was handled.
    return true;
}
//---------------------------------------------------------------------------
bool YourGame::handleRadio(const CEGUI::EventArgs& e)
{
    using namespace CEGUI;

    // get the ID of the selected radio button
    CEGUI::uint id = static_cast<RadioButton*>(static_cast<const 
        WindowEventArgs&>(e).window)->getSelectedButtonInGroup()->getID();
    // get the StaticImage window
    Window* img = 
        WindowManager::getSingleton().getWindow("Demo7/Window2/Image1");

    // set an image into the StaticImage according to the ID of the 
    // selected radio button.
    switch (id)
    {
    case 0:
        img->setProperty("Image", "set:BackgroundImage image:full_image");
        break;

    case 1:
        img->setProperty("Image", "set:TaharezLook image:MouseArrow");
        break;

    default:
        img->setProperty("Image", "");
        break;
    }

    // event was handled
    return true;
}
//---------------------------------------------------------------------------
bool YourGame::handleCheck(const CEGUI::EventArgs& e)
{
    using namespace CEGUI;

    // show or hide the FrameWindow containing the multi-line editbox 
    // according to the state of the checkbox widget
    WindowManager::getSingleton().getWindow("Demo7/Window3")->
        setVisible(static_cast<Checkbox*>(static_cast<const 
        WindowEventArgs&>(e).window)->isSelected());

    // event was handled.
    return true;
}
//---------------------------------------------------------------------------
bool YourGame::InitializeCegui()
{
    using namespace CEGUI;

    // we will use of the WindowManager.
    WindowManager& winMgr = WindowManager::getSingleton();

    // load scheme and set up defaults
    SchemeManager::getSingleton().loadScheme("TaharezLook.scheme");
    System::getSingleton().setDefaultMouseCursor("TaharezLook", "MouseArrow");
    FontManager::getSingleton().createFont("Commonwealth-10.font");

    // load an image to use as a background
    ImagesetManager::getSingleton().createImagesetFromImageFile(
        "BackgroundImage", "GPN-2000-001437.tga");

    // here we will use a StaticImage as the root, then we can use it to 
    // place a background image
    Window* background = winMgr.createWindow("TaharezLook/StaticImage", 
        "background_wnd");

    // set position and size
    background->setPosition(UVector2(cegui_reldim(0), cegui_reldim( 0)));
    background->setSize(UVector2(cegui_reldim(1), cegui_reldim( 1)));
    // disable frame and standard background
    background->setProperty("FrameEnabled", "false");
    background->setProperty("BackgroundEnabled", "false");
    // install this as the root GUI sheet
    System::getSingleton().setGUISheet(background);

    // load the windows for Demo7 from the layout file.
    Window* sheet = winMgr.loadWindowLayout("Demo7Windows.layout");
    // attach this to the 'real' root
    background->addChildWindow(sheet);
    // set-up the contents of the list boxes.
    createListContent();
    // initialise the event handling.
    initDemoEventWiring();
    if (_CrtCheckMemory() == FALSE)
    {
        NiMessageBox("Memory leak","memory error");
    }
    // success!
    return true;
}
//---------------------------------------------------------------------------
bool YourGame::CreateScene()
{
    // Because our scene will have some billboards with alpha, we use 
    // a NiAlphaAccumulator in order that our alpha gets sorted and drawn
    // correctly.
    NiAlphaAccumulator* pkAccum = NiNew NiAlphaAccumulator;
    m_spRenderer->SetSorter(pkAccum);

    NiStream kStream;

    // Load in the scenegraph for our world...
    bool bSuccess = kStream.Load(
		"../../../../GraphicsTechDemos/SimpleApp/Data/TheClockAndTheOcularis.nif");
    
    if (!bSuccess)
    {
        NiMessageBox("TheClockAndTheOcularis.nif file could not be loaded!", 
            "NIF Error");
        return false;
    }

    m_spScene = (NiNode*) kStream.GetObjectAt(0);
    NIASSERT(NiIsKindOf(NiNode, m_spScene));

    // We expect the world to have been exported with a camera, so we 
    // look for it here.
    m_spCamera = FindFirstCamera(m_spScene);
    if (!m_spCamera)
    {
        NiMessageBox("The NIF file has no camera!", "Camera Error");
        return false;
    }

	HidePointer();
    if (_CrtCheckMemory() == FALSE)
    {
        NiMessageBox("Memory leak","memory error");
    }
    return bSuccess;
}
//---------------------------------------------------------------------------
bool YourGame::CreateFrame()
{
    if (!NiApplication::CreateFrame())
    {
        return false;
    }

    NiDefaultClickRenderStep* pkMainStep = NiDynamicCast(
        NiDefaultClickRenderStep, m_spFrame->GetRenderStepByName(
        m_kMainRenderStepName));
    NIASSERT(pkMainStep);

    // Attach CEGUI click after the main 3D scene rendering
    gui.AppendGUI(pkMainStep);
    gui.InitializeCegui(this);
	return true;
}
//---------------------------------------------------------------------------
